package com.aliyunlog.query;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSON;
import com.aliyun.openservices.log.Client;
import com.aliyun.openservices.log.common.LogContent;
import com.aliyun.openservices.log.common.LogItem;
import com.aliyun.openservices.log.common.QueriedLog;
import com.aliyun.openservices.log.exception.LogException;
import com.aliyun.openservices.log.response.GetLogsResponse;
import com.aliyunlog.conf.Constant;
import com.aliyunlog.model.LogConf;
import com.aliyunlog.model.LogItemResult;
import com.aliyunlog.utils.DateUtil;
import com.aliyunlog.utils.JsonFileReadUtil;
import com.aliyunlog.utils.LogItemWarnSender;

/**
 * 
 * @author tanson lam
 * @creation 2017年6月24日
 * 
 */
public class LogQuery {
	
	private final static Logger log = Logger.getLogger(LogQuery.class);
	
	private String endpoint; // 所属区域匹配的 Endpoint
	private String accessKeyId; // 使用您的阿里云访问密钥 AccessKeyId
	private String accessKeySecret; // 使用您的阿里云访问密钥
	private LogItemWarnSender logItemWarnSender;
	private final static int MAXLINELENGTH = 255; // 报文最大长度

	public LogQuery(String endpoint, String accessKeyId, String accessKeySecret) {
		this.endpoint = endpoint;
		this.accessKeyId = accessKeyId;
		this.accessKeySecret = accessKeySecret;
	}

    /**
     *
     * @param project
     * @param logstore
     * @param topic  主题 例如:wmpbasic wmpgateway
     * @param queryKey 查询条件
     * @param logMaxLimit 报文长度
     * @param lastExecTime 最后一次执行时间
     * @return
     * @throws LogException
     */
	public LogItemResult queryLog(String project, String logstore,
			String topic, String queryKey,
			List<String> filters,
			int logMaxLimit, int mt, Date lastExecTime) throws LogException {

        // 构建一个客户端实例
        Client client = new Client(endpoint, accessKeyId, accessKeySecret);

        // 监控当前到几秒之前的数据
        // 例如: 60秒为1分钟, 300秒为5分钟,
        // 1周(week)=604800秒(s)
        // 1天(d)=86400秒(s)
        int time = mt; 
        Date now = new Date();
        /*
            日志开始时间 默认为当前时间15分钟之前
            例如: 当前14:30:00 则变为 14:15:00-14:30:00
        */
        int from = (int) (now.getTime() / 1000 - time);
        log.debug(" from time = " + from);

        // 日志结束时间
		int to = (int) (now.getTime() / 1000);
        log.debug(" to time = " + to);
		GetLogsResponse resp = client.GetLogs(project, logstore, from, to,
				topic, queryKey);
		log.debug("count:" + resp.GetCount());
		List<QueriedLog> list = resp.GetLogs();
		StringBuffer titleString = new StringBuffer();
		titleString.append("SEND_TIME:" + DateUtil.toDateStr(now)+"\n"+
				"MONITOR_TIME:" + DateUtil.toDateStr(new Date(((now.getTime()/1000) - time) * 1000)) +"至" + DateUtil.toDateStr(now))
				.append("\n").append(
				"PROJECT:" + project + ",LOGSTORE:" + logstore + ",TOPIC:"
						+ topic + ",QUERYKEY:" + queryKey).append("\n");
		int line = 1;
		List<String> messageList = new ArrayList<String>();
		for (QueriedLog resultLog : list) {
			StringBuffer outLogString = new StringBuffer();
			LogItem logItem = resultLog.GetLogItem();
			if(line == 1) outLogString.append("\n");
			outLogString.append("【" + line + "】");
            Set<String> msgSet = new HashSet<String>();
			for (LogContent content : logItem.GetLogContents()) {

                log.debug("content: " + JSON.toJSONString(content));

				if (content.GetKey().equals("time")) {
					log.debug(content.GetKey() + ":" + content.GetValue());
					outLogString.append("时间").append(":")
							.append(content.GetValue()).append("\n");
				}

                if(content.GetKey().equals("logContent")){
                    int nextLineIndex = -1;
                    String logMessage = content.GetValue();
                    log.debug("sub start logMessage => " + logMessage);
                    if (StringUtils.isNotEmpty(logMessage)
                            && (nextLineIndex = logMessage
                            .indexOf("\n")) > -1) {
                        logMessage = content.GetValue().substring(0,
                                nextLineIndex);
                    }
                    msgSet.add(logMessage);
                    log.debug("sub end logMessage => " + logMessage);
                }
				if (content.GetKey().equals("message")) {
					int nextLineIndex = -1;
					String logMessage = content.GetValue();
                    log.debug("sub start logMessage => " + logMessage);
					if (StringUtils.isNotEmpty(logMessage)
							&& (nextLineIndex = logMessage
									.indexOf("\n")) > -1) {
						logMessage = content.GetValue().substring(0,
								nextLineIndex);
					}
                    msgSet.add(logMessage);
                    log.debug("sub end logMessage => " + logMessage);
				}
			}
            log.debug("msgSet size = " + msgSet.size());
            for (String msg : msgSet){
            	
            	if(filterData(filters, msg)){
            		outLogString = new StringBuffer("");
            		continue;
            	}
            	
                // 如果符合规则 则全部展示预警错误  否则则展示部分预警错误
                if (msg.length() > logMaxLimit) {
                    msg = msg.substring(0, logMaxLimit - 1);
                }
                log.debug("msg :" + msg);
                outLogString.append("报文").append(":").append(msg)
                        .append("\n");
            }
            if(StringUtils.isNotBlank(outLogString.toString())){
            	messageList.add(outLogString.toString());
            	line++;
            }
		}
		return new LogItemResult(titleString.toString(), messageList);
	}

	
	/**
	 * 过滤数据配置
	 * @param filters
	 * @param msg
	 * @return
	 */
	public static boolean filterData(List<String> filters, String msg){
		if(CollectionUtils.isNotEmpty(filters)){
			for (String str : filters) {
				if(StringUtils.contains(msg, str)){
					return true;
				}
			}
		}
		return false;
	}
	
    // public void runQueryTask(final String project, final String logstore,
	// final String topic,
	// final String queryKey) {
	// TimerTask task = new TimerTask() {
	// @Override
	// public void run() {
	// try {
	// LogItemResult logItemResult = queryLog(project, logstore, topic,
	// queryKey);
	// logItemWarnSender.sendLogItemResult(logItemResult);
	// } catch (LogException e) {
	// e.printStackTrace();
	// }
	// }
	// };
	// Timer timer = new Timer();
	// long delay = 0;
	// long intevalPeriod = 300 * 1000;
	// timer.scheduleAtFixedRate(task, delay, intevalPeriod);
	// }

	public static void main(String[] args) {
		String endpoint = "cn-hangzhou.log.aliyuncs.com";
		String accessKeyId = "LTAItn3KhtQWkZ3L";
		String accessKeySecret = "idZjlyp4PxgAPYhpgSCoIuoSdaWmDD";
		LogConf logConf = JsonFileReadUtil.getLogConf("alog2017_wotianxia-cyb_wmpinner");
		System.out.println(logConf);

		/*
		 * String dingdingUrl =
		 * "https://oapi.dingtalk.com/robot/send?access_token=7dc0fc8c99e5aac9b4a59a0f1038d3f29223aacec839f0488e1b3410accaf1fa"
		 * ; String project = "alog2017"; String logstore = "cyb2017"; String
		 * topic = "wmpbasic"; String queryKey = "ERROR";
		 */
		LogQuery query = new LogQuery(endpoint, accessKeyId, accessKeySecret);
		try {
			LogItemResult queryLog = query.queryLog(logConf.getProject(),
					logConf.getLogstore(), logConf.getTopic(),
					logConf.getQueryKey(), logConf.getFilterPatterns(), logConf.getLogMaxLimit(), logConf.getMonitorTime(), null);
//			LogItemWarnSender.sendLogItemResult(queryLog, logConf.getDingdingUrl());
			System.out.println(JSON.toJSONString(queryLog));
		} catch (LogException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// query.runQueryTask(logConf.getProject(), logConf.getLogstore(),
		// logConf.getTopic(), logConf.getQueryKey());
	}

    /**
     * 发送消息给钉钉聊天机器人
     * @param confCode  配置code
     * @param lastExecTime 最后一次执行时间
     */
	public static void sendDingDing(String confCode, String queryKey, Date lastExecTime) {
		String endpoint = Constant.ENDPOINT;
		String accessKeyId = Constant.ACCESS_KEY_ID;
		String accessKeySecret = Constant.ACCESS_KEY_SECRET;
        log.debug(" confMap = " + JsonFileReadUtil.getLogConfMap());
		LogConf logConf = JsonFileReadUtil.getLogConf(confCode);
		if (logConf == null) {
			log.debug("根据confCode=" + confCode
					+ " 发现配置不存在的 ====== 这波很亏 ");
			return;
		}
		LogQuery query = new LogQuery(endpoint, accessKeyId, accessKeySecret);
		try {
			LogItemResult logItemResult = query.queryLog(logConf.getProject(),
					logConf.getLogstore(), logConf.getTopic(),
                    StringUtils.isBlank(queryKey) ? logConf.getQueryKey() : queryKey, 
                    		logConf.getFilterPatterns(),logConf.getLogMaxLimit(), logConf.getMonitorTime(), lastExecTime);
			LogItemWarnSender.sendLogItemResult(logItemResult,
					logConf.getDingdingUrl());
		} catch (LogException e) {
			log.debug(" 发送给钉钉的消息出错~ 这就很瓜皮 ");
			e.printStackTrace();
		}
	}
}